parser grammar AnasintJava;

options {
	tokenVocab = AnalexJava;
	backtrack = true;
}

tokens{
	INST;
	FUNCION;
	DECLARACION;
	IDENTIFICADOR;
	STATEMENTS;
	EXPRESSION;
	ARGUMENTOS;
}

@header {
	import java2instruction.*;
}

@members {
	SymbolTable st = new SymbolTable();
	int blockLevel = 0;
}

program returns [SymbolTable res]
	: (definition)* EOF
	{
		res = st;
	}
	;
definition
	: dataDefinition
	| functionDefinition
	;	
dataDefinition
	: (INT | LONG) declarator[Kind.VAR, "hola"] PUNTOYCOMA
	;
declarator
	[Kind kind, String type]
	: id=ID 
	{
		st.add(new Symbol(id.getText(), kind, blockLevel, type));		
	}
	;
functionDefinition
	: (INT | LONG)? functionHeader functionBody
	;
functionHeader
	: declarator[Kind.FUNC, "hola"] parameterList
	;
parameterList
	: ABREPAR (identifierList)? CIERRAPAR (parameterDeclaration)* 
	;
identifierList
	: declarator[Kind.PARAM, "hola"] (COMA declarator[Kind.PARAM, "hola"])*
	;
parameterDeclaration
	: INT declarator[Kind.PARAM, "hola"] (COMA declarator[Kind.PARAM, "hola"])* PUNTOYCOMA
	;
functionBody
	: ABRELLAVE { blockLevel++; } dataDefinitions statements CIERRALLAVE { blockLevel--; }
	;
dataDefinitions
	: (dataDefinition*)
	;
statements
	: (statement)*
	;	
statement
	: expression PUNTOYCOMA
	| ABRELLAVE  { blockLevel++; } (dataDefinition)* (statement)* CIERRALLAVE { blockLevel--; } 
	| IF ABREPAR expression CIERRAPAR statement (ELSE statement)?
	| WHILE ABREPAR expression CIERRAPAR statement
	| BREAK PUNTOYCOMA
	| CONTINUE PUNTOYCOMA
	| RETURN2 expression? PUNTOYCOMA
	;
expression
	: binary (COMMA binary)*
	;
binary
	: ID IGUAL binary
	| ID INCREMENTA binary
	| ID DECREMENTA binary
	| ID MULTIPLICA binary
	| ID DIVIDE binary
	| ID MODULO binary
	| unary MAS binary
	| unary MENOS binary
	| unary POR binary
	| unary DIVIDIDO binary
	| unary PORCENTAJE binary
	| unary AND binary
	| unary BARRA binary
	| unary ELEVADO binary
	| unary MENOR binary
	| unary MAYOR binary
	| unary MENORIGUAL binary
	| unary MAYORIGUAL binary
	| unary EQUIVALENTE binary
	| unary DISTINTO binary
	| unary
	;
unary
	: DOBLEMAS ID
	| DOBLEMENOS ID
	| primary
	;
primary
	: ID
	| NUMERO
	| ABREPAR expression CIERRAPAR
	| ID ABREPAR argumentList? CIERRAPAR
	; 
argumentList
	: binary (COMA binary)*
	;